package com.jblog.common.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

/**
 * 图片操作工具类,包括切割,放大缩小,水印等
 */
public final class ImageUtils {
    /**
     * 切割图片.
     * @param srcImg
     *            源图片
     * @param x
     *            起始位置
     * @param y
     *            结束位置
     * @param w
     *            切割宽度
     * @param h
     *            切割高度
     * @throws IOException
     * @author leo
     */
    public static BufferedImage ClipImg(BufferedImage srcImg, int x, int y,
            int w, int h) throws IOException {
        BufferedImage buffImg = srcImg;

        int height = buffImg.getHeight();
        int width = buffImg.getWidth();

        if (x > width)
            x = width;
        if (y > height)
            x = height;

        if ((x + w) > width)
            w = width - x;
        if ((y + h) > height)
            h = height - y;

        BufferedImage newImg = buffImg.getSubimage(x, y, w, h);

        return newImg;
    }

    public static BufferedImage ClipImg(String srcImg, int x, int y, int w,
            int h) throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));
        return ClipImg(buffImg, x, y, w, h);
    }

    /**
     * 缩放图片
     * 
     * @param srcImg
     * @param tarImg
     * @param scaleWidth
     *            宽缩放率
     * @param scaleHeight
     *            高缩放率
     * @throws IOException
     * 
     */

    public static BufferedImage scaleImg(BufferedImage srcImg,
            double scaleWidth, double scaleHeight) throws IOException {
        BufferedImage buffImg = srcImg;
        double height = buffImg.getHeight() * scaleHeight;
        double width = buffImg.getWidth() * scaleWidth;
        BufferedImage newImg = new BufferedImage((int) width, (int) height,
                buffImg.getType());

        Graphics2D g = newImg.createGraphics();

        g.setColor(Color.WHITE);
        g.fillRect(0, 0, (int) width, (int) height);
        g.scale(scaleWidth, scaleHeight);

        g.drawImage(buffImg, 0, 0, null);

        return newImg;
    }

    public static BufferedImage scaleImg(String srcImg, double scaleWidth,
            double scaleHeight) throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return scaleImg(buffImg, scaleWidth, scaleHeight);
    }

    /**
     * 
     * @param srcImg
     * @param tarImg
     * @param angle
     *            旋转率
     * @throws IOException
     * 
     *             旋转图片
     */
    public static BufferedImage roateImg(BufferedImage srcImg, double angle)
            throws IOException {
        BufferedImage buffImg = srcImg;
        int oldWidth = buffImg.getWidth();
        int oldHeight = buffImg.getHeight();

        int width = (int) (Math.cos(angle) * oldWidth + Math.sin(angle)
                * oldHeight);
        int height = (int) (Math.sin(angle) * oldWidth + Math.cos(angle)
                * oldHeight);

        BufferedImage newImg = new BufferedImage(width, height, buffImg
                .getType());

        Graphics2D g = newImg.createGraphics();

        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        g.translate(width - oldWidth * Math.cos(angle), 0);
        g.rotate(angle);

        g.drawImage(buffImg, 0, 0, null);

        return newImg;
    }

    public static BufferedImage roateImg(String srcImg, double angle)
            throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return roateImg(buffImg, angle);
    }

    /**
     * 
     * @param srcImg
     *            来源文件
     * @param text
     *            写入的文本
     * @param fontHeight
     *            字体大小
     * @param color
     *            颜色
     * @param font
     *            字体
     * @param x
     *            左上角起的左右位置
     * @param y
     *            左上角起的上下位置
     * @param alpha
     *            透明度
     * @throws IOException
     * 
     *             写水印
     */
    public static BufferedImage writeImg(BufferedImage srcImg, String text,
            int fontHeight, Color color, String font, int x, int y, float alpha)
            throws IOException {
        BufferedImage buffImg = srcImg;
        Graphics2D g = buffImg.createGraphics();

        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                alpha));
        Font Gfont = new Font(font, Font.PLAIN, fontHeight);
        g.setFont(Gfont);
        g.setColor(color);
        g.drawString(text, x, y);

        return buffImg;
    }

    public static BufferedImage writeImg(String srcImg, String text,
            int fontHeight, Color color, String font, int x, int y, float alpha)
            throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return writeImg(buffImg, text, fontHeight, color, font, x, y, alpha);
    }

    /**
     * 把图片写入图片
     * 
     * @param srcImg
     *            原图片
     * @param tarImg
     *            目标图片
     * @param x
     *            左上角起的左右位置
     * @param y
     *            左上角起的上下位置
     * @param alpha
     *            alpha 透明度
     * @return 图片缓冲
     * @throws IOException
     */
    public static BufferedImage writeImgToImg(BufferedImage srcImg,
            BufferedImage tarImg, int x, int y, float alpha) throws IOException {
        BufferedImage buffImg = srcImg;
        Graphics2D g = buffImg.createGraphics();

        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                alpha));

        g.drawImage(tarImg, null, x, y);

        return buffImg;
    }

    /**
     * 把图片写入图片
     * 
     * @param srcImg
     *            原图片路径
     * @param tarImg
     *            目标图片路径
     * @param x
     *            左上角起的左右位置
     * @param y
     *            左上角起的上下位置
     * @param alpha
     *            alpha 透明度
     * @return 图片缓冲
     * @throws IOException
     */
    public static BufferedImage writeImgToImg(String srcImg, String tarImg,
            int x, int y, float alpha) throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));
        BufferedImage target = ImageIO.read(new File(tarImg));

        return writeImgToImg(buffImg, target, x, y, alpha);
    }

    /**
     * 
     * @param srcImg
     *            来源文件
     * @param tarImg
     *            目标文件
     * @throws IOException
     *             异常
     * 
     *             图片滤镜
     */
    public static BufferedImage filterImg(BufferedImage srcImg, float[] element)
            throws IOException {
        BufferedImage buffImg = srcImg;
        BufferedImage targetImg = new BufferedImage(buffImg.getWidth(), buffImg
                .getHeight(), buffImg.getType());

        Kernel kernel = new Kernel(3, 3, element);
        ConvolveOp op = new ConvolveOp(kernel);

        op.filter(buffImg, targetImg);

        return targetImg;

    }

    public static BufferedImage filterImg(String srcImg, float[] element)
            throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));
        return filterImg(buffImg, element);

    }

    public static float[] filter1 = { 0.0f, -1.0f, 0.0f, -1.0f, 4f, -1.0f,
            0.0f, -1.0f, 0.0f };
    public static float[] filter2 = { 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f,
            0.1f, 0.1f };
    public static float[] filter3 = { -1.0f, 0.0f, -1.0f, 0.0f, 4f, 0.0f,
            -1.0f, 0.0f, -1.0f };

    /**
     * 把图片缓冲写入文件
     * 
     * @param targetImgName
     *            目标文件
     * @param imgType
     *            文件类型
     * @param img
     *            图片缓冲
     * @throws IOException
     */
    public static void writeImg(String targetImgName, String imgType,
            BufferedImage img) throws IOException {
        ImageIO.write(img, imgType, new File(targetImgName));
    }

    /**
     * 灰度化图像，适用于bmp图像。
     * 
     * @param srcImg
     * @return
     */
    public static BufferedImage grayImage(BufferedImage srcImg) {

        Raster imgData = srcImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY; y < height; y++) {

            for (int x = minX; x < width; x++) {

                int rgb = srcImg.getRGB(x, y);

                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。

                int gray = (int) (0.3 * color.getRed() + 0.59
                        * color.getGreen() + 0.11 * color.getBlue());

                Color newColor = new Color(gray, gray, gray);

                srcImg.setRGB(x, y, newColor.getRGB());

            }
        }

        return srcImg;
    }

    /**
     * 灰度化图像，适用于bmp图像。
     * 
     * @param srcImg
     * @return
     * @throws IOException
     */
    public static BufferedImage grayImage(String srcImg) throws IOException {

        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return grayImage(buffImg);
    }

    /**
     * 二值化图像.
     * 
     * @param srcImg
     * @return
     * @throws IOException
     */
    public static BufferedImage binarizationImage(BufferedImage buffImg)
            throws IOException {

        int average = averageValue(buffImg, false, 256);

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY; y < height; y++) {

            for (int x = minX; x < width; x++) {

                int rgb = buffImg.getRGB(x, y);

                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。

                int value = 255 - color.getBlue();

                if (value > average) {

                    Color newColor = new Color(0, 0, 0);

                    buffImg.setRGB(x, y, newColor.getRGB());
                } else {
                    Color newColor = new Color(255, 255, 255);

                    buffImg.setRGB(x, y, newColor.getRGB());
                }

            }
        }

        return buffImg;
    }

    /**
     * 二值化图像.
     * 
     * @param srcImg
     * @return
     * @throws IOException
     */
    public static BufferedImage binarizationImage(String srcImg)
            throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return binarizationImage(buffImg);
    }

    /**
     * 取得平均的灰值数。
     * 
     * @param buffImg
     * @param above
     * @param checkPoint
     * @return
     */
    private static int averageValue(BufferedImage buffImg, boolean above,
            int checkPoint) {
        int point = 0;
        int count = 0;

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY; y < height; y++) {

            for (int x = minX; x < width; x++) {

                int rgb = buffImg.getRGB(x, y);

                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。

                int value = 255 - color.getBlue();

                if (above) {
                    if (value > checkPoint) {
                        point++;
                        count = count + value;
                    }
                } else {
                    if (value < checkPoint) {
                        point++;
                        count = count + value;
                    }
                }

            }
        }

        return count / point;
    }

    /**
     * 计算一个点周围点的平均数。
     * 
     * @param buffImg
     * @param checkPoint
     * @return
     * @throws IOException
     */
    private static int averagePointImage(BufferedImage buffImg, int checkPoint)
            throws IOException {

        int point = 0;
        int count = 0;

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY + 1; y < height - 1; y++) {

            for (int x = minX + 1; x < width - 1; x++) {

                Color color1, color2, color3, color4, color5, color6, color7, color8;

                int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0, x5 = 0, y5 = 0, x6 = 0, y6 = 0, x7 = 0, y7 = 0, x8 = 0, y8 = 0;

                x1 = x - 1;
                y1 = y - 1;
                x2 = x;
                y2 = y - 1;
                x3 = x + 1;
                y3 = y - 1;
                x4 = x - 1;
                y4 = y;
                x5 = x + 1;
                y5 = y;
                x6 = x - 1;
                y6 = y + 1;
                x7 = x;
                y7 = y + 1;
                x8 = x + 1;
                y8 = y + 1;

                color1 = new Color(buffImg.getRGB(x1, y1));
                color2 = new Color(buffImg.getRGB(x2, y2));
                color3 = new Color(buffImg.getRGB(x3, y3));
                color4 = new Color(buffImg.getRGB(x4, y4));
                color5 = new Color(buffImg.getRGB(x5, y5));
                color6 = new Color(buffImg.getRGB(x6, y6));
                color7 = new Color(buffImg.getRGB(x7, y7));
                color8 = new Color(buffImg.getRGB(x8, y8));

                if (color1.getBlue() != checkPoint)
                    count++;
                if (color2.getBlue() != checkPoint)
                    count++;
                if (color3.getBlue() != checkPoint)
                    count++;
                if (color4.getBlue() != checkPoint)
                    count++;
                if (color5.getBlue() != checkPoint)
                    count++;
                if (color6.getBlue() != checkPoint)
                    count++;
                if (color7.getBlue() != checkPoint)
                    count++;
                if (color8.getBlue() != checkPoint)
                    count++;

                point++;

            }
        }

        return count / point;
    }

    /**
     * 中值滤波1。
     * 
     * @param srcImg
     * @param checkPoint
     * @param less
     * @return
     * @throws IOException
     */
    public static BufferedImage medianFilter(BufferedImage buffImg,
            int checkPoint, boolean less) throws IOException {

        int average = averagePointImage(buffImg, checkPoint);
        int count = 0;

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY + 1; y < height - 1; y++) {

            for (int x = minX + 1; x < width - 1; x++) {

                Color color1, color2, color3, color4, color5, color6, color7, color8;

                int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0, x5 = 0, y5 = 0, x6 = 0, y6 = 0, x7 = 0, y7 = 0, x8 = 0, y8 = 0;

                x1 = x - 1;
                y1 = y - 1;
                x2 = x;
                y2 = y - 1;
                x3 = x + 1;
                y3 = y - 1;
                x4 = x - 1;
                y4 = y;
                x5 = x + 1;
                y5 = y;
                x6 = x - 1;
                y6 = y + 1;
                x7 = x;
                y7 = y + 1;
                x8 = x + 1;
                y8 = y + 1;

                color1 = new Color(buffImg.getRGB(x1, y1));
                color2 = new Color(buffImg.getRGB(x2, y2));
                color3 = new Color(buffImg.getRGB(x3, y3));
                color4 = new Color(buffImg.getRGB(x4, y4));
                color5 = new Color(buffImg.getRGB(x5, y5));
                color6 = new Color(buffImg.getRGB(x6, y6));
                color7 = new Color(buffImg.getRGB(x7, y7));
                color8 = new Color(buffImg.getRGB(x8, y8));

                if (color1.getBlue() != checkPoint)
                    count++;
                if (color2.getBlue() != checkPoint)
                    count++;
                if (color3.getBlue() != checkPoint)
                    count++;
                if (color4.getBlue() != checkPoint)
                    count++;
                if (color5.getBlue() != checkPoint)
                    count++;
                if (color6.getBlue() != checkPoint)
                    count++;
                if (color7.getBlue() != checkPoint)
                    count++;
                if (color8.getBlue() != checkPoint)
                    count++;

                if (less && count <= average)
                    buffImg.setRGB(x, y, new Color(checkPoint, checkPoint,
                            checkPoint).getRGB());
                if (!less && count >= average)
                    buffImg.setRGB(x, y, new Color(checkPoint, checkPoint,
                            checkPoint).getRGB());

                count = 0;

            }
        }

        return buffImg;
    }

    /**
     * 中值滤波1。
     * 
     * @param srcImg
     * @param checkPoint
     * @param less
     * @return
     * @throws IOException
     */
    public static BufferedImage medianFilter(String srcImg, int checkPoint,
            boolean less) throws IOException {

        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return medianFilter(buffImg, checkPoint, less);
    }

    /**
     * 中值滤波方法二。
     * 
     * @param srcImg
     * @return
     * @throws IOException
     */
    public static BufferedImage delPoint2(String srcImg) throws IOException {

        BufferedImage image = ImageIO.read(new File(srcImg));

        int ih, iw;
        int[] pixels;

        iw = image.getWidth();
        ih = image.getHeight();
        pixels = new int[iw * ih];

        PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih,
                pixels, 0, iw);
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 对图像进行中值滤波，Alpha值保持不变
        ColorModel cm = ColorModel.getRGBdefault();
        for (int i = 1; i < ih - 1; i++) {
            for (int j = 1; j < iw - 1; j++) {
                int red, green, blue;
                int alpha = cm.getAlpha(pixels[i * iw + j]);

                // int red2 = cm.getRed(pixels[(i - 1) * iw + j]);
                int red4 = cm.getRed(pixels[i * iw + j - 1]);
                int red5 = cm.getRed(pixels[i * iw + j]);
                int red6 = cm.getRed(pixels[i * iw + j + 1]);
                // int red8 = cm.getRed(pixels[(i + 1) * iw + j]);

                // 水平方向进行中值滤波
                if (red4 >= red5) {
                    if (red5 >= red6) {
                        red = red5;
                    } else {
                        if (red4 >= red6) {
                            red = red6;
                        } else {
                            red = red4;
                        }
                    }
                } else {
                    if (red4 > red6) {
                        red = red4;
                    } else {
                        if (red5 > red6) {
                            red = red6;
                        } else {
                            red = red5;
                        }
                    }
                }

                // int green2 = cm.getGreen(pixels[(i - 1) * iw + j]);
                int green4 = cm.getGreen(pixels[i * iw + j - 1]);
                int green5 = cm.getGreen(pixels[i * iw + j]);
                int green6 = cm.getGreen(pixels[i * iw + j + 1]);
                // int green8 = cm.getGreen(pixels[(i + 1) * iw + j]);

                // 水平方向进行中值滤波
                if (green4 >= green5) {
                    if (green5 >= green6) {
                        green = green5;
                    } else {
                        if (green4 >= green6) {
                            green = green6;
                        } else {
                            green = green4;
                        }
                    }
                } else {
                    if (green4 > green6) {
                        green = green4;
                    } else {
                        if (green5 > green6) {
                            green = green6;
                        } else {
                            green = green5;
                        }
                    }
                }

                // int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]);
                int blue4 = cm.getBlue(pixels[i * iw + j - 1]);
                int blue5 = cm.getBlue(pixels[i * iw + j]);
                int blue6 = cm.getBlue(pixels[i * iw + j + 1]);
                // int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);

                // 水平方向进行中值滤波
                if (blue4 >= blue5) {
                    if (blue5 >= blue6) {
                        blue = blue5;
                    } else {
                        if (blue4 >= blue6) {
                            blue = blue6;
                        } else {
                            blue = blue4;
                        }
                    }
                } else {
                    if (blue4 > blue6) {
                        blue = blue4;
                    } else {
                        if (blue5 > blue6) {
                            blue = blue6;
                        } else {
                            blue = blue5;
                        }
                    }
                }
                pixels[i * iw + j] = alpha << 24 | red << 16 | green << 8
                        | blue;
            }
        }

        // 将数组中的象素产生一个图像

        Image targetImage = Toolkit.getDefaultToolkit().createImage(
                new MemoryImageSource(iw, ih, pixels, 0, iw));

        BufferedImage bufferedImage = new BufferedImage(targetImage
                .getWidth(null), targetImage.getHeight(null),
                BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bufferedImage.createGraphics();
        g.drawImage(targetImage, 0, 0, null);

        return bufferedImage;
    }

//    private static int[][] template1 = { { 0, 0, 0, 0, 1, 0, 1, 1, 1 },
//            { 1, 1, 1, 0, 1, 0, 0, 0, 0 }, { 1, 0, 0, 1, 1, 0, 1, 0, 0 },
//            { 0, 0, 1, 0, 1, 1, 0, 0, 1 }
//
//    };
//
//    private static int[][] template2 = { { 1, 0, 1, 1, 1, 1, 1, 1, 1 },
//            { 1, 1, 1, 0, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 0, 1 },
//            { 1, 1, 1, 1, 1, 0, 1, 1, 1 }
//
//    };

    /**
     * 细线化图像,使用Hilditch算法.
     * 
     * @param srcImg
     * @param checkPoint
     * @param less
     * @return
     * @throws IOException
     */
    public static BufferedImage hilditchImage(BufferedImage buffImg)
            throws IOException {

        List<Point> delPointList = new ArrayList<Point>();

        int count = 0;

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY + 1; y < height - 1; y++) {

            for (int x = minX + 1; x < width - 1; x++) {

                Color color = new Color(buffImg.getRGB(x, y));

                if (color.getBlue() == 255)
                    buffImg.setRGB(x, y, new Color(0, 0, 0).getRGB());
                else
                    buffImg.setRGB(x, y, new Color(1, 1, 1).getRGB());

            }
        }

        do {

            delPointList.clear();

            // int color;

            // for(int y=minY+2;y<height-1;y++){
            //				
            // for(int x=minX+1;x<width-2;x++){
            //					  
            // int result=0;
            // int px,py;
            //					  
            // for(int t=0;t<4;t++){
            //						  
            // int[] tNow=template1[t];
            //						  
            // int tP=0;
            //						  
            // for(int j=0;j<=2;j++){
            // for(int i=0;i<=2;i++){
            // px=x-1+j;
            // py=y-1+i;
            //								  
            // color=new Color(buffImg.getRGB(px, py)).getBlue();
            //								  
            // result=result+Math.abs(tNow[tP]-color);
            //								  
            // tP++;
            // }
            // }
            //						  
            // if(result==0){
            // buffImg.setRGB(x,y, new Color(0,0,0).getRGB());
            // break;
            // }
            //						  
            // result=0;
            // }
            //					  
            // for(int t=0;t<4;t++){
            //						  
            // int[] tNow=template2[t];
            //						  
            // int tP=0;
            //						  
            // for(int j=0;j<=2;j++){
            // for(int i=0;i<=2;i++){
            // px=x-1+j;
            // py=y-1+i;
            //								  
            // color=new Color(buffImg.getRGB(px, py)).getBlue();
            //								  
            // result=result+Math.abs(tNow[tP]-color);
            //								  
            // tP++;
            // }
            // }
            //						  
            // if(result==0){
            //							  
            // for(int j=0;j<=2;j++){
            // for(int i=0;i<=2;i++){
            // px=x-1+j;
            // py=y-1+i;
            //									  
            // buffImg.setRGB(px,py, new Color(1,1,1).getRGB());
            // }
            // }
            //							  
            // break;
            //							  
            // }
            //						  
            //						  
            // }
            //					  
            // }
            // }

            for (int y = minY + 2; y < height - 1; y++) {

                for (int x = minX + 1; x < width - 2; x++) {

                    count = 0;

                    int p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14;

                    int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0, x5 = 0, y5 = 0, x6 = 0, y6 = 0, x7 = 0, y7 = 0, x8 = 0, y8 = 0, x9 = 0, y9 = 0, x10 = 0, y10 = 0, x11 = 0, y11 = 0, x12 = 0, y12 = 0, x13 = 0, y13 = 0, x14 = 0, y14 = 0;

                    x1 = x - 1;
                    y1 = y - 1; // 上左
                    x2 = x;
                    y2 = y - 1; // 上中
                    x3 = x + 1;
                    y3 = y - 1; // 上右

                    x4 = x - 1;
                    y4 = y; // 中左
                    x5 = x + 1;
                    y5 = y; // 中右

                    x6 = x - 1;
                    y6 = y + 1; // 下左
                    x7 = x;
                    y7 = y + 1; // 下中
                    x8 = x + 1;
                    y8 = y + 1; // 下右

                    x6 = x - 1;
                    y6 = y + 1; // 下左
                    x7 = x;
                    y7 = y + 1; // 下中
                    x8 = x + 1;
                    y8 = y + 1; // 下右

                    x9 = x - 1;
                    y9 = y - 2; // 上上左
                    x10 = x;
                    y10 = y - 2; // 上上中
                    x11 = x + 1;
                    y11 = y - 2; // 上上右

                    x12 = x + 2;
                    y12 = y - 1; // 右右上
                    x13 = x + 2;
                    y13 = y; // 右右中
                    x14 = x + 2;
                    y14 = y + 1; // 右右下

                    p1 = new Color(buffImg.getRGB(x1, y1)).getBlue();// 上左 p4
                    p2 = new Color(buffImg.getRGB(x2, y2)).getBlue();// 上中 p3
                    p3 = new Color(buffImg.getRGB(x3, y3)).getBlue();// 上右 p2

                    p4 = new Color(buffImg.getRGB(x4, y4)).getBlue();// 中左 p5
                    p0 = new Color(buffImg.getRGB(x, y)).getBlue(); // 中中 p0
                    p5 = new Color(buffImg.getRGB(x5, y5)).getBlue();// 中右 p1

                    p6 = new Color(buffImg.getRGB(x6, y6)).getBlue();// 下左 p6
                    p7 = new Color(buffImg.getRGB(x7, y7)).getBlue();// 下中 p7
                    p8 = new Color(buffImg.getRGB(x8, y8)).getBlue();// 下右 p9

                    p9 = new Color(buffImg.getRGB(x9, y9)).getBlue();// 下左 p6
                    p10 = new Color(buffImg.getRGB(x10, y10)).getBlue();// 下中 p7
                    p11 = new Color(buffImg.getRGB(x11, y11)).getBlue();// 下右 p9

                    p12 = new Color(buffImg.getRGB(x12, y12)).getBlue();// 下左 p6
                    p13 = new Color(buffImg.getRGB(x13, y13)).getBlue();// 下中 p7
                    p14 = new Color(buffImg.getRGB(x14, y14)).getBlue();// 下右 p9

                    if (p0 != 1) {
                        continue;
                    }

                    count = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;

                    if (!(count >= 2 && count <= 6))
                        continue;

                    if (((p2 == 0) & (p3 == 1) ? 1 : 0)
                            + ((p3 == 0) & (p5 == 1) ? 1 : 0)
                            + ((p5 == 0) & (p8 == 1) ? 1 : 0)
                            + ((p8 == 0) & (p7 == 1) ? 1 : 0)
                            + ((p7 == 0) & (p6 == 1) ? 1 : 0)
                            + ((p6 == 0) & (p4 == 1) ? 1 : 0)
                            + ((p4 == 0) & (p1 == 1) ? 1 : 0)
                            + ((p1 == 0) & (p2 == 1) ? 1 : 0) != 1)
                        continue;

                    int c2 = 0;

                    c2 = ((p10 == 0) & (p11 == 1) ? 1 : 0)
                            + ((p11 == 0) & (p3 == 1) ? 1 : 0)
                            + ((p3 == 0) & (p5 == 1) ? 1 : 0)
                            + ((p5 == 0) & (p0 == 1) ? 1 : 0)
                            + ((p0 == 0) & (p4 == 1) ? 1 : 0)
                            + ((p4 == 0) & (p1 == 1) ? 1 : 0)
                            + ((p1 == 0) & (p9 == 1) ? 1 : 0)
                            + ((p9 == 0) & (p10 == 1) ? 1 : 0);

                    if (!((p2 * p5 * p4 == 0) || c2 != 1))
                        continue;

                    int c5 = 0;

                    c5 = ((p3 == 0) & (p12 == 1) ? 1 : 0)
                            + ((p12 == 0) & (p13 == 1) ? 1 : 0)
                            + ((p13 == 0) & (p14 == 1) ? 1 : 0)
                            + ((p14 == 0) & (p8 == 1) ? 1 : 0)
                            + ((p8 == 0) & (p7 == 1) ? 1 : 0)
                            + ((p7 == 0) & (p0 == 1) ? 1 : 0)
                            + ((p0 == 0) & (p2 == 1) ? 1 : 0)
                            + ((p2 == 0) & (p3 == 1) ? 1 : 0);

                    if (!((p2 * p5 * p7 == 0) || c5 != 1))
                        continue;

                    delPointList.add(new Point(x, y));

                }
            }

            for (Point point : delPointList) {
                buffImg.setRGB(point.x, point.y, new Color(0, 0, 0).getRGB());
            }

        } while (!delPointList.isEmpty());

        for (int y = minY + 1; y < height - 1; y++) {

            for (int x = minX + 1; x < width - 1; x++) {

                Color color = new Color(buffImg.getRGB(x, y));

                if (color.getBlue() == 0)
                    buffImg.setRGB(x, y, new Color(255, 255, 255).getRGB());
                else
                    buffImg.setRGB(x, y, new Color(0, 0, 0).getRGB());

            }
        }

        return buffImg;
    }

    /**
     * 细线化图像,使用Hilditch算法.
     * 
     * @param srcImg
     * @param checkPoint
     * @param less
     * @return
     * @throws IOException
     */
    public static BufferedImage hilditchImage(String srcImg) throws IOException {

        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        return hilditchImage(buffImg);
    }

    /**
     * 把一张大图像分割成小块。
     * 
     * @param srcImg
     * @param checkPoint
     * @return
     * @throws IOException
     */
    public static Rectangle[] clipImage(String srcImg, final int checkPoint)
            throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        List<Integer> xList = new ArrayList<Integer>();

        Raster imgData = buffImg.getData();
        int now = 0;
        int prev = 0;

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int x = minX; x < width; x++) {

            for (int y = minY; y < height; y++) {
                int p0;
                p0 = new Color(buffImg.getRGB(x, y)).getBlue();
                if (p0 == checkPoint) {
                    now++;
                }
            }

            if ((now != 0 && prev == 0))
                xList.add(x);
            if ((now == 0 && prev != 0))
                xList.add(x);

            prev = now;
            now = 0;
        }

        Rectangle[] rectangles = new Rectangle[xList.size() / 2];
        Integer[] xPoint = xList.toArray(new Integer[0]);

        int t = 0;
        for (int i = 0; i < xPoint.length; i = i + 2) {
            rectangles[t++] = new Rectangle(xPoint[i], xPoint[i + 1], 0, 0);
        }

        for (Rectangle rectangle : rectangles) {
            now = 0;
            prev = 0;

            for (int y = minY; y < height; y++) {

                for (int x = rectangle.getX1(); x < rectangle.getX2(); x++) {
                    int p0;

                    p0 = new Color(buffImg.getRGB(x, y)).getBlue();

                    if (p0 == checkPoint) {
                        now++;
                    }
                }

                if ((now != 0 && prev == 0))
                    rectangle.setY1(y);
                if ((now == 0 && prev != 0))
                    rectangle.setY2(y);

                prev = now;
                now = 0;
            }

        }

        return rectangles;
    }

    /**
     * 显示图片中每个颜色点。
     * 
     * @param srcImg
     * @throws IOException
     */
    public static void showImg(String srcImg) throws IOException {

        BufferedImage buffImg = ImageIO.read(new File(srcImg));
        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY; y < height; y++) {

            for (int x = minX; x < width; x++) {

                int rgb = buffImg.getRGB(x, y);

                Color color = new Color(rgb);

                System.out.print(" " + color.getRed() + "-" + color.getGreen()
                        + "-" + color.getBlue() + " ");

            }

            System.out.println();
        }
    }

    /**
     * 反向图片的颜色.
     * 
     * @param srcImg
     * @return
     * @throws IOException
     */
    public static BufferedImage reverseImage(String srcImg) throws IOException {
        BufferedImage buffImg = ImageIO.read(new File(srcImg));

        Raster imgData = buffImg.getData();

        int minX = imgData.getMinX();
        int minY = imgData.getMinY();
        int height = imgData.getHeight();
        int width = imgData.getWidth();

        for (int y = minY; y < height; y++) {

            for (int x = minX; x < width; x++) {

                int rgb = buffImg.getRGB(x, y);

                Color color = new Color(rgb); // 根据rgb的int值分别取得r,g,b颜色。

                Color newColor = new Color(255 - color.getRed(), 255 - color
                        .getGreen(), 255 - color.getBlue());

                buffImg.setRGB(x, y, newColor.getRGB());

            }
        }

        return buffImg;
    }
    
    @SuppressWarnings("unused")
    private static class Rectangle {
        private int x1,y1;
        private int x2,y2;
        
        public Rectangle(int x1,int x2,int y1,int y2){
            this.x1=x1;
            this.x2=x2;
            this.y1=y1;
            this.y2=y2;
        }
        
        public int getX1() {
            return x1;
        }
        public void setX1(int x1) {
            this.x1 = x1;
        }
        public int getX2() {
            return x2;
        }
        public void setX2(int x2) {
            this.x2 = x2;
        }
        public int getY1() {
            return y1;
        }
        public void setY1(int y1) {
            this.y1 = y1;
        }
        public int getY2() {
            return y2;
        }
        public void setY2(int y2) {
            this.y2 = y2;
        }
        
        public int getPerimeter(){
            return Math.abs(x1)+Math.abs(x2)+Math.abs(y1)+Math.abs(y2);
        }
        
        public int getArea(){
            return Math.abs(x1-x2)*Math.abs(y1-y2);
        }
        
        public int getWidth(){
            return Math.abs(x1-x2);
        }
        
        public int getHeight(){
            return Math.abs(y1-y2);
        }
        
    }

    public static void main(String[] args) throws IOException {
        // writeImg(".\\a.jpg","jpg",ClipImg(".\\test.jpg",0,0,300,200));
        //writeImg("./b.jpg", "jpg", scaleImg("./a.jpg", 0.1, 0.1));
//         roateImg(".\\test.jpg",".\\a.jpg",1);

         writeImg(".\\a.jpg","测试",100,Color.BLUE,"宋体",10,200,0.6f);
        // writeImg(".\\target.jpg","jpg",writeImgToImg(".\\a.jpg",".\\b.gif",0,0,0.7f));
        // writeImg(".\\a.jpg","jpg",filterImg(".\\test1.jpg",filter3));

        // BufferedImage image=ImageIO.read(new File("5.bmp"));

        // writeImg("gray.bmp","bmp",image);

        // writeImg("blur.bmp","bmp",blurImage("test.bmp"));

        // writeImg("gray.bmp","bmp",grayImage("a1.bmp"));
        //		
        // writeImg("denoise.bmp","bmp",denoiseImage("gray.bmp"));
        //		
        // writeImg("reverse.bmp","bmp",reverseImage("denoise.bmp"));
        //		
        // writeImg("nopoint.bmp","bmp",delPoint("reverse.bmp",255,true));
        //		
        // writeImg("nopoint1.bmp","bmp",filterImg("nopoint.bmp",filter1));

        // writeImg("nopoint1.bmp","bmp",delPoint("nopoint.bmp",255,true));

        // showImg("gray.bmp");

        // 过程灰度化->二值化->中值滤波->细线化。

        // writeImg("nopoint.bmp","bmp",hilditchImage(medianFilter(binarizationImage(grayImage("genimg.jpg")),255,true)));
        //		
        // int index=0;
        // for(Rectangle rectangle:clipImage("nopoint.bmp",0))
        // writeImg("nopoint"+(index++)+".bmp","bmp",ClipImg("nopoint.bmp",rectangle.getX1(),rectangle.getY1(),rectangle.getWidth(),rectangle.getHeight()));

        // writeImg("line.bmp","bmp",lineImage("denoise.bmp"));

    }
}
